import io
import xlrd
import random
import os
import redis
from threading import Thread
from datetime import datetime
from django.db.models import Q, QuerySet
from django.contrib.auth.hashers import make_password, check_password
from Model.models import LoginLog as Login, HandleLog as Handle, User
from mgtServer.settings import MEDIA_ROOT, UPLOAD_DIR, LOG_DIR
from onu.models import OntRecord
from xlutils.copy import copy
from pypinyin import pinyin, Style

res = {}
token_expired_time = dict()
token_username = dict()
token_all_current = set()
username_token = dict()


def encryptPassword(password):
    """
    密码加密
    :param password: password
    :return: hash_password
    """
    new_password = make_password(password, None, 'pbkdf2_sha256')
    return new_password


def checkPassword(password_one, password_two):
    """
    验证密码
    :param password_one: 传递过来的密码
    :param password_two: 数据库的密码
    :return: true or false
    """
    password_bool = check_password(password_one, password_two)
    return password_bool


def check_text(text):
    """
    检查字段是否存在
    """
    if text is not None and text != '':
        return True
    else:
        return False


def getReferrerIp(request) -> object:
    """
    获取来源IP
    :param request
    :return ipAddress
    """
    if request.META.get('HTTP_X_FORWARDED_FOR'):
        ip = request.META.get("HTTP_X_FORWARDED_FOR")
    else:
        ip = request.META.get("REMOTE_ADDR")
    return ip


def getCurrentUser(request) -> object:
    """
    :param request
    :return Curenet user
    """
    token = request.META.get('HTTP_AUTHORIZATION')
    username = token_username[token]
    if username == 'superAdmin':
        return '超级管理员'
    user = User.objects.get(Q(telephone=username) | Q(user_name=username) | Q(email=username)).real_name
    return user


def createLoginLog(login_status: str, user: str, ip: str):
    """
    :param login_status  登录状态
    :param user 登录人
    :param ip  来源IP
    """
    Login.objects.create(login_status=login_status, login_user=user, login_date=datetime.now(), login_ip=ip)


def createHandleLog(handle: str, user: str, content: dict or list):
    """
    :param handle 操作权限
    :param user 操作人
    :param content 操作json
    """
    Handle.objects.create(handle=handle, handle_name=user, handle_date=datetime.now(), handle_content=content)


def getRandomPassword():
    """
    生成6位宽带账号随机密码
    :return:password
    """
    length = 6
    chars = 'qwertyupasdfghjkzxcvbnm23456789'
    password = "".join([random.choice(chars) for _ in range(length)])
    return password


def readFile(name):
    files_address = MEDIA_ROOT / name
    excel = xlrd.open_workbook(files_address, encoding_override='utf8')
    sheet1 = excel.sheet_by_index(0)
    row = sheet1.nrows
    title_list = sheet1.row_values(0)
    result = []
    for i in range(1, row):
        row_value = sheet1.row_values(i)
        row_dict = dict()
        for index, value in enumerate(row_value):
            row_dict[title_list[index]] = value
        result.append(row_dict)
    return result


def getFileBytes(name):
    files_address = MEDIA_ROOT / name
    excel = xlrd.open_workbook(files_address, encoding_override='utf8')
    writeBook = copy(excel)
    output = io.BytesIO()
    writeBook.save(output)
    value = output.getvalue()
    return value


def getLetterByCity(city: str):
    if city.find('市') != -1:
        city = city.strip('市')
    result = pinyin(city, style=Style.FIRST_LETTER)
    letter = ''.join([''.join(i) for i in result])
    return letter


def createFile(number: str, file: object, fileType: str):
    suffix = file.name.split('.')[1]
    uploadPath = UPLOAD_DIR / f'{number}_{fileType}.{suffix}'
    file_path = open(uploadPath, 'wb+')
    for chunk in file.chunks():
        file_path.write(chunk)
    return uploadPath


def addTime(date, day):
    import datetime
    return date + datetime.timedelta(days=day)


def async_method(f):
    def wrapper(*args, **kwargs):
        thr = Thread(target=f, args=args, kwargs=kwargs)
        thr.start()

    return wrapper


@async_method
def write_log(data, ip, port, userrole=None, level=None):
    file_path = LOG_DIR / f"{ip}_{port}"
    if not file_path.exists():
        file_path.mkdir()

    if userrole:
        file_name = "%s_%s_%s_%srun.log" % (ip, port, str(datetime.now())[:10], userrole)
    else:
        file_name = "%s_%s_%srun.log" % (ip, port, str(datetime.now())[:10])

    file = os.path.join(file_path, file_name)
    with open(file, "a", encoding='utf8') as f:
        f.write("%s  " % str(datetime.now())[:19])
        f.write(data)
        f.write("\n")

    # 错误日志
    if level == "error":
        file_name = "%s_%s_%serror.log" % (ip, port, str(datetime.now())[:10])
        file = os.path.join(file_path, file_name)
        with open(file, "a") as f:
            f.write("%s  " % str(datetime.now())[:19])
            f.write(data)
            f.write("\n")
    return True


def Save_OntRecord(olt_id, equipment, community, olt_type, register_type, frameid, slotid, board_port, ont_num, sn,
                   line_template, business_template, business_intimal, business_outer, gemport):
    OntRecord.objects.create(olt_id=olt_id,
                             equipment=equipment,
                             community=community,
                             olt_type=olt_type,
                             register_type=register_type,
                             frameid=frameid,
                             slotid=slotid,
                             board_port=board_port,
                             ont_num=ont_num,
                             sn=sn,
                             line_template=line_template,
                             business_template=business_template,
                             business_intimal=business_intimal,
                             business_outer=business_outer,
                             gemport=gemport,
                             created_time=datetime.now()
                             )
    return


class redisPool():
    def __init__(self):
        Pool = redis.ConnectionPool(host='127.0.0.1', port=6379, max_connections=100, encoding='utf-8', db=0)
        # 从池子中拿一个链接
        self.conn = redis.Redis(connection_pool=Pool, decode_responses=True)

    def redis_get(self, redis_key):
        result = self.conn.get(redis_key)
        if result:
            result = result.decode()
        return result

    def redis_del(self, redis_key):
        result = self.conn.delete(redis_key)
        return result


def getSourceLen(source: list or QuerySet):
    """
    :param source 查询数据集
    """
    return source.__len__()


def getDataPaging(source: QuerySet, pageSize: int, current: int):
    """
    :param source 查询数据集
    :param pageSize 每页条数
    :param current 当前页
    """
    return list(source.values()[pageSize * current - pageSize:pageSize * current])


def rebootRadius():
    """
    重启readius服务
    """
    os.system("ps -ef | grep radiusd | awk '{print $2}' | /usr/bin/xargs /usr/bin/kill -9")
    os.system("radiusd")
    return True
